<template>
	<div class="printer-div">
		<div class='item white_bg margin_top30 padding10'>
			<ul class='padding10'>
				<li>
					<span class='left_tip'>开启蓝牙适配器</span>
					<switch :checked='isOpen' color='#F65A4B' @change="openBluetooth" />
				</li>
				<li>
					<span class='left_tip'>手机名称</span>
					<span>{{phoneName}}</span>
				</li>
			</ul>
		</div>
		
		<p class='search_machina margin_top30' @click='searchBluetoothDevice'>
			{{isSearching? '搜索中...(点击停止)': '搜索蓝牙设备'}}
		</p>
		
		<p class='search_machina margin_top30' @click="printData()">
			发送数据
		</p>
		
		<div class='item white_bg margin_top30'>
			<p class='title'>已配对设备：</p>
			<ul class='padding10 searched-box'>
				<li v-for='(item,index,key) in matedList' :key='key'
					v-if='item.connected'>
					<view class="uni-list-cell">
						<view class="uni-list-cell-navigate uni-navigate-right">
							<span>{{(item.name=='' || item.name=='未知设备')? item.deviceId: item.name}}</span>
						</view>
					</view>
				</li>
			</ul>
		</div>
		
		<div class='item white_bg margin_top30'>
			<p class='title'>可用设备：</p>
			<ul class='padding10 searched-box'>
				<li v-for='(item,index,key) in matedList' :key='key'
					@click.stop='toConnect(index)' v-if='!item.connected'>
					<view class="uni-list-cell">
						<view class="uni-list-cell-navigate uni-navigate-right">
							<span>
								{{(item.name=='' || item.name=='未知设备')? item.deviceId: item.name}}
								<span class='connect' v-show='item.isConnect'>连接中...</span>
							</span>
						</view>
					</view>
				</li>
			</ul>
		</div>
		
		<!--温馨提示-->
		<div class='wenxin_tip margin_top30 padding10'>
			<p class='title'>温馨提示：</p>
			<p>1.打开蓝牙打印机</p>
			<p>2.打开手机蓝牙设置，部分(oppo、vivo、金立等)安卓手机需要打开手机“定位”设置</p>
			<p>3.部分安卓手机限制微信使用蓝牙功能，需要进行开启“手机设置--应用管理--微信--权限--蓝牙权限”允许</p>
			<p>4.以上操作都已尝试，还是无法找到打印机，请重启打印机后再次搜索。</p>
		</div>
	</div>
</template>

<script>
import {showToast} from '../../utils/index.js';
export default {
	data() {
		return {
			isOpen: false,  //蓝牙是否开启
			phoneName: '',  //手机名称
			isSearching: false,  //搜索中
			matedList: [],  //已配对设备
			connectIndex: -1,  //正在连接的设备序列号
			deviceId: '',  //设备id
			serviceId: '',  //服务id,
			characteristicId: '',  //特征值id
		};
	},
	onShow() {
		this.getPhoneInfo();
		this.openBuletooth();
	},
	methods: {
		//初始化蓝牙适配器
		openBuletooth(){
			var self = this;
			uni.openBluetoothAdapter({
				success(res) {
					self.isOpen = true;
					//监听蓝牙适配器状态变化
					setTimeout(()=>{
						uni.onBluetoothAdapterStateChange(function(res){
							self.isSearching = res.discovering;
						});
					},1500);
					//监听搜索到新设备
					setTimeout(()=>{
						uni.onBluetoothDeviceFound(function(res){
							var device = res.devices[0];
							device.isConnect = false; //是否在连接
							device.connected = false; //是否已连接
							var isHave = false; //该设备是否已经在列表中了
							for(var i=0,len=self.matedList.length; i<len; i++){
								if(self.matedList[i].deviceId == device.deviceId){
									isHave = true;
									break;
								}
							}
							if(!isHave){
								console.log('设备', device);
								setTimeout(()=>{
									//获取搜索到的蓝牙设备列表
									uni.getBluetoothDevices({
										services: [],
										allowDuplicatesKey: false,
										interval: 0,
										success(res){
											var devices = res.devices;
											console.log('全部设备',devices)
											for(var i=0,len1=devices.length; i<len1; i++){
												let the_device = devices[i];
												if(the_device.deviceId == device.deviceId){
													device.name = the_device.name;
													self.matedList.push(device);
													break;
												}
											}
										}
									});
								},1000);
							}
						});
					},1500);
				},
				fail(){
					self.isOpen = false;
					self.$forceUpdate();
					self.errTip();
				}
			});
		},
		//开启或者关闭蓝牙
		openBluetooth(e){
			var status = e.target.value;
			this.isOpen = status;
			var self = this;
			if(status){  //开启
				this.openBuletooth();
			}else{ //关闭蓝牙适配器
				uni.closeBluetoothAdapter({
					success(){
						self.isSearching = false;
						self.matedList = [];
						uni.hideLoading();
					},
					fail(){
						showToast('关闭失败')
					}
				})
			}
		},
		//蓝牙设备未打开的错误提示
		errTip(){
			uni.showModal({
				title: '提示',
				content: '连接失败：手机蓝牙或定位未打开',						
				showCancel: false
			});
		},
		//获取手机设备信息
		getPhoneInfo(){
			const res = uni.getSystemInfoSync();
			var platform = res.platform;  //平台
			var version = res.version;  //版本号
			if((platform=='andriod' && version<'6.5.7') ||
				(platform=='ios' && version<'6.5.6')){
				showToast('当前微信版本过低，请更新至最新版本');
				setTimeout(()=>{
					uni.navigateBack({
						delta:1
					});
				},1500);
			};
			this.phoneName = res.model;
		},
		//停止搜索
		stopSearch(){
			this.isSearching = false;
			uni.stopBluetoothDevicesDiscovery({
				
			});
		},
		//搜索蓝牙设备
		searchBluetoothDevice(){
			if(this.isSearching){  //搜索中，使之停止搜索
				this.stopSearch();
				return;
			}
			var self = this;
			if(this.isOpen){  //已打开
				//开始搜索设备
				self.isSearching = true;
				setTimeout(()=>{
					uni.startBluetoothDevicesDiscovery({
						services: [],
						allowDuplicatesKey: false,
						success(res){
							
						}
					});
				},1500);
			}else{
				this.errTip();
			}
		},
		//连接设备
		toConnect(index){
			var self = this;
			this.matedList[index].isConnect = true;
			uni.showLoading({
				title: '连接蓝牙设备中...'
			});
			var deviceId = self.matedList[index].deviceId;
			self.deviceId = deviceId;
			uni.createBLEConnection({
				deviceId: deviceId,
				timeout: 60*1000,  //超时时间一分钟
				success(res){
					uni.hideLoading();
					showToast('连接成功','success');
					self.connectIndex = index;
					self.matedList[index].connected = true;
					//停止蓝牙搜索
					self.stopSearch();
					self.getBlueService();
					//去除其他的连接
					self.matedList.forEach((item,i)=>{
						if(i!=index){
							item.isConnect = false;
							item.connected = false;
						}
					});
				},
				fail(){
					showToast('连接失败');
					self.matedList[index].isConnect = false;
				}
			});
		},
		//获取蓝牙设备的service服务，
		getBlueService(){
			var self = this;
			setTimeout(()=>{
				uni.getBLEDeviceServices({
					deviceId: self.deviceId,
					success(res){
						var services = res.services; //设备服务，数组
						console.log('服务列表',services);
						//获取哪个设备中有读写能力的蓝牙设备
						for(var i=0,len=services.length; i<len; i++){
							self.getBlueServiceCharacteristics(services[i].uuid);
						};
					}
				});
			},1500);
		},
		//获取蓝牙设备特征值
		getBlueServiceCharacteristics(serviceId){
			var self = this;
			setTimeout(()=>{
				uni.getBLEDeviceCharacteristics({
					deviceId: self.deviceId,
					serviceId: serviceId,
					success(res){
						var characteristics = res.characteristics;
						console.log('特征值',characteristics);
						for(var i=0,len=characteristics.length; i<len; i++){
							if ((characteristics[i].properties.notify || characteristics[i].properties.indicate) &&
                                (characteristics[i].properties.read && characteristics[i].properties.write)) {
                                console.log(characteristics[i].uuid, '蓝牙特征值 ==========')
                                /* 获取蓝牙特征值 */
                                var notifyCharacteristicsId = characteristics[i].uuid;
								self.serviceId = serviceId;
								self.characteristicId = notifyCharacteristicsId;
                                // 启用低功耗蓝牙设备特征值变化时的 notify 功能
								uni.showLoading({
									title: '配对...'
								});
                                self.notifyBlueCharValueChange()
                            }
						}
					}
				});
			},1500);
		},
		//启动notify蓝牙监听功能，然后使用 wx.onBLECharacteristicValueChange用来监听蓝牙设备传递数据
		notifyBlueCharValueChange(){
			var self = this;
			setTimeout(()=>{
				uni.notifyBLECharacteristicValueChange({
					deviceId: self.deviceId,
					serviceId: self.serviceId,
					characteristicId: self.characteristicId,
					state: true,
					complete(res){
						uni.hideLoading();
						uni.onBLECharacteristicValueChange((res)=>{
							console.log('notify值', res)
						});
					},
					fail(e){
						showToast('启用失败。');
						console.log(e)
					}
				});
			},1500);
		},
		buf2string(){
			var arr = Array.prototype.map.call(new Uint8Array(buffer), x= x);
			return arr.map((char, i)=>{
				return String.fromCharCode(char);
			}).join("");
		},
		//ArrayBuffer转16进制字符串
		ab2hex(buffer){
			const hexArr = Array.prototype.map.call(
				new Uint8Array(buffer),
				function(bit){
					return ('00' + bit.toString(16)).slice(-2)
				}
			)
			return hexArr.join('');
		},
		//接收数据
		receiveData(buf){
			return this.hexCharCodeToStr(this.ab2hex(buf));
		},
		/*转成可展会的文字*/
		hexCharCodeToStr(hexCharCodeStr) {
			var trimedStr = hexCharCodeStr.trim();
			var rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr;
			var len = rawStr.length;
			var curCharCode;
			var resultStr = [];
			for(var i = 0; i < len; i = i + 2){
				curCharCode = parseInt(rawStr.substr(i, 2), 16);
				resultStr.push(String.fromCharCode(curCharCode));
			}
			return resultStr.join('');
		},
		//向蓝牙设备发送数据
		sendData(str) {
			let self = this;
			let dataBuffer = new ArrayBuffer(str.length);
			let dataView = new DataView(dataBuffer);
			for (var i=0,len=str.length; i<len; i++) {
				dataView.setUint8(i, str.charAt(i).charCodeAt());
			}
			let dataHex = self.ab2hex(dataBuffer);
			var writeDatas = self.hexCharCodeToStr(dataHex);
			uni.writeBLECharacteristicValue({
				deviceId: self.deviceId,
				serviceId: self.serviceId,
				characteristicId: self.characteristicId,
				value: dataBuffer,
				success: function (res) {
					console.log('发送的数据：' + writeDatas);
				},
				fail: function (res) {
					showToast('发送数据失败');
				},
				complete: function (res) {
				}
			});
		},
		//让蓝牙打印数据
		printData(){
			var str = `HI, everyone, 
						my name is burtyang`;
			console.log('数据', str);
			var self = this;
			setTimeout(()=>{
				self.sendData(str);
			},1500);
		}
	}
}
</script>

<style lang="less">
.left_tip{
	min-width: 120upx;
}
/**搜索蓝牙设备**/
.search_machina{
	line-height: 70upx;
	text-align: center;
	color: #F65A4B;
	background: #fff;
}
.item{
	p{
		font-size: 24upx;
		line-height: 50upx;
		background: #E5E5E5;
		padding-left: 20upx;
		color: #888;
	}
	ul{
		li{
			min-height: 80upx;
			display: flex;
			align-items: center;
			justify-content: space-between;
		}
		li+li{
			border-top:1px solid #eee;
		}
	}
	/**可用设备**/
	ul.searched-box{
		li{
			.uni-list-cell{
				width: 100%;
				span.connect{
					font-size: 20upx;
					color: #888;
					margin-left: 10upx;
				}
			}
		}
	}
}
/**温馨提示**/
.wenxin_tip{
	font-size: 24upx;
	color: #999;
	p.title{
		margin-bottom: 10upx;
	}
}
</style>
